package hotel.callback.oversea.controller;

import hotel.base.oversea.constant.MeituanConstants;
import hotel.base.oversea.utils.DateUtil;
import hotel.base.oversea.utils.Result;
import hotel.callback.oversea.service.MtHotelGoodsService;
import hotel.callback.oversea.task.MeituanCheckOneHotelGoodsDataTask;
import hotel.callback.oversea.task.MeituanPartTimeQueryPriceTask;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

//import hotel.callback.oversea.task.MeituanPartTimeQueryStatusTask;

/**
 * 美团酒店产品价格Controller
 * @author qiuyy
 * @date 2020-05-15
 */
@Slf4j
@RestController
@RequestMapping("/mtHotelGoodsPriceCallback")
@Api(value = "MtHotelGoodsPriceController", tags = {"美团酒店产品价格接口"})
public class MtHotelGoodsPriceCallbackController {
    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    MeituanCheckOneHotelGoodsDataTask meituanCheckOneHotelGoodsDataTask;
    @Autowired
    MeituanPartTimeQueryPriceTask meituanPartTimeQueryPriceTask;
//    @Autowired
//    MeituanPartTimeQueryStatusTask meituanPartTimeQueryStatusTask;

    @Autowired
    MtHotelGoodsService mtHotelGoodsService;

    /**
     * 24小时查询，未来10天房态价格rp接口
     *
     * 用途：定时器主动查询-价格判断价格变化推送携程更新（过滤为上架的酒店）
     *  //上游要求：业务参数，hotelId和goodsId传其一，最好hotelId，个数支持最多10
     * @return
     */
    @PostMapping("/allTimeQueryUpHotelPriceStatus")
    @ApiOperation(value = "24小时主动查询价格房态",notes="必须经过auth授权")
    public Result<Object> getChangeMonthGoodsIdsByOneHotelId(@RequestBody Map map){
        //log.info("getChangeMonthGoodsIdsByOneHotelId  进入方法，当前队列size",redisTemplate.opsForList().size(MeituanConstants.REIDS_POP_ALL_SALE_ROOM_ABOUT_MT_HOTEL_IDS));

        String timestamp = (String)map.get("timestamp");//每次定时器调用接口传唯一timestamp，为了方便查询线程日志

        Integer days = (Integer)map.get("days");

        //log.info("getChangeMonthGoodsIdsByOneHotelId {} 定时器调用美团校验酒店房态价格方法  执行时间 {}，map={}",timestamp,DateUtil.getCurrTime(),JSON.toJSONString(map));

        int countTask = MeituanConstants.ALL_TIME_TASK_COUNT;//每一秒120次；；；；；；；；；；；；；；7200 /60 = 120次/1秒

        if(null != redisTemplate.opsForValue().get("allTimeQueryUpHotelPriceStatus_count_task")){
            countTask = (Integer) redisTemplate.opsForValue().get("allTimeQueryUpHotelPriceStatus_count_task");
        }
        //Integer days = mtHotelGoodsService.getDaysCommonBaseSet();
        for (int k = 0; k < countTask; k++) {
            List<Long> oneDateHotelIds = new ArrayList<>();
            for (int j = 0; j < 10; j++) {//每次线程10个酒店，接口最多10个酒店,定时器发起一次生成10个线程=10x10=100家酒店，太多家酒店携程也消费不了，暂时未10个线程
                //log.info("{} into  j={}",timestamp,j);
                Integer oneDateHotelId = (Integer)redisTemplate.opsForList().rightPop(MeituanConstants.REIDS_POP_ALL_SALE_ROOM_ABOUT_MT_HOTEL_IDS);//每pop一次该list集合中vo少一个
                if(!ObjectUtils.isEmpty(oneDateHotelId)){
                    oneDateHotelIds.add(Long.valueOf(oneDateHotelId));//添加到集合中
                }else{
                    if(null != oneDateHotelIds && oneDateHotelIds.size()>0){
                        meituanCheckOneHotelGoodsDataTask.executeCheckTenHotelGoods(oneDateHotelIds,days,timestamp+"_"+k+"_"+j);
                    }
                    log.info("{} 当前coutTask，酒店处理完且酒店队列无数据： k={},j={}",timestamp,k,j);
                    return new Result<>();//return 结束当前
                }
                if(oneDateHotelIds.size()==10){
                    meituanCheckOneHotelGoodsDataTask.executeCheckTenHotelGoods(oneDateHotelIds,days,timestamp+"_"+k+"_"+j);
                    oneDateHotelIds = new ArrayList<>();
                }
            }
            try {
                Thread.sleep(10);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        log.info("getChangeMonthGoodsIdsByOneHotelId {} 24小时主动查询价格房态 结束时间 {},countTask={}",timestamp,DateUtil.getCurrTime(),countTask);

        return new Result();
    }

    /**
     * 节点时间定时器主动查询1个月产品价格（利用房态接口和价格日历接口（分散rp接口压力，rp接口用于实时查询））
     * @return
     *//*
    @PostMapping("/partTimeQueryStatusInfo")
    @ApiOperation(value = "节点时间定时器主动查询1个月产品房态",notes="必须经过auth授权")
    public Result<Object> partTimeQueryStatusInfo(@RequestBody Map map){
        String timestamp = (String)map.get("timestamp");//每次定时器调用接口传唯一timestamp，为了方便查询线程日志
        int countTask = MeituanConstants.PART_STATUS_TIME_TASK_COUNT;//20个线程，一次一个酒店，共查询20次接口//内部一次查询未来30天数据返回是有跨度的所以不用再调用三十次

        if(null != redisTemplate.opsForValue().get("partTimeQueryStatusInfo_count_task")){//10个线程，则一次调用该方法，处理10个酒店
            countTask = (Integer) redisTemplate.opsForValue().get("partTimeQueryStatusInfo_count_task");
        }

        Integer timeHotel = MeituanConstants.PART_STATUS_TIME_HOTEL_COUNT;//接口每次上送1个酒店，则1个线程1个酒店

        for (int k = 0; k < countTask; k++) {
            List<Long> oneDateHotelIds = new ArrayList<>();
                for (int j = 0; j < timeHotel; j++) {
                Integer oneDateHotelId = (Integer)redisTemplate.opsForList().rightPop(MeituanConstants.REIDS_POP_ALL_SALE_ROOM_ABOUT_MT_HOTEL_IDS_FOR_RLSTATUS);//每pop一次该list集合中vo少一个
                if(!ObjectUtils.isEmpty(oneDateHotelId)){
                    oneDateHotelIds.add(Long.valueOf(oneDateHotelId));
                }else{
                    //已无hotelid，判断list中有无待处理数据，发起异步线程，调用第三方接口
                    if(null != oneDateHotelIds && oneDateHotelIds.size()>0){
                        meituanPartTimeQueryStatusTask.executeCheckOneHotelGoods(String.valueOf(oneDateHotelId),timestamp+"_"+k+"_"+j);
                    }
                    log.info("{} 当前房态coutTask，酒店处理完且酒店队列无数据： k={},j={}",timestamp,k,j);
                    return new Result<>();//return 结束当前
                }
                if(oneDateHotelIds.size()==timeHotel){//每次一个酒店
                    //发起异步线程，调用第三方接口
                    meituanPartTimeQueryStatusTask.executeCheckOneHotelGoods(String.valueOf(oneDateHotelId),timestamp+"_"+k+"_"+j);
                    log.info("{} 当前房态coutTask，酒店处理完： k={},j={}",timestamp,k,j);
                    oneDateHotelIds = new ArrayList<>();
                }
            }
            *//*try {
                Thread.sleep(10);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }*//*
        }
        log.info("partTimeQueryStatusInfo {} 节点时间定时器主动查询1个月产品房态 结束时间 {}，countTask={}",timestamp,DateUtil.getCurrTime(),countTask);

        return new Result();
    }*/
    /**
     * 节点时间定时器主动查询1个月产品价格（利用房态接口和价格日历接口（分散rp接口压力，rp接口用于实时查询））
     * @return
     */
    @PostMapping("/partTimeQueryPriceInfo")
    @ApiOperation(value = "节点时间定时器主动查询1个月产品价格",notes="必须经过auth授权")
    public Result<Object> partTimeQueryPriceInfo(@RequestBody Map map){
        String timestamp = (String)map.get("timestamp");//每次定时器调用接口传唯一timestamp，为了方便查询线程日志
        Integer days = (Integer)map.get("days");

        int countTask = MeituanConstants.PART_PRICE_TIME_TASK_COUNT;

        if(null != redisTemplate.opsForValue().get("partTimeQueryPriceInfo_count_task")){
            countTask = (Integer) redisTemplate.opsForValue().get("partTimeQueryPriceInfo_count_task");
        }
        Integer timeHotel = MeituanConstants.PART_PRICE_TIME_HOTEL_COUNT;

        for (int k = 0; k < countTask; k++) {
            //log.info("{} into  k={}",timestamp,k);
            // 每一次countTask线程 拿10个酒店上送；内部方法task异步 10个酒店处理15天调用15次；8个异步task共8x15=120次
            List<Long> oneDateHotelIds = new ArrayList<>();
            for (int j = 0; j < timeHotel; j++) {//每次线程10个酒店，每次上送一个酒店，由于上游返回没有按酒店集合返而是产品集合返所以按一个去查询
                //log.info("{} into  j={}",timestamp,j);
                Integer oneDateHotelId = (Integer)redisTemplate.opsForList().rightPop(MeituanConstants.REIDS_POP_ALL_SALE_ROOM_ABOUT_MT_HOTEL_IDS_FOR_RLPRICE);//每pop一次该list集合中vo少一个
                if(!ObjectUtils.isEmpty(oneDateHotelId)){
                    oneDateHotelIds.add(Long.valueOf(oneDateHotelId));
                }else{

                    //已无hotelid，判断list中有无待处理数据，发起异步线程，调用第三方接口
                    if(null != oneDateHotelIds && oneDateHotelIds.size()>0){
                        //log.info("调用task1",JSON.toJSONString(oneDateHotelIds),days,timestamp+"_"+k+"_"+j);
                        meituanPartTimeQueryPriceTask.executeCheckOneHotelGoods("ALL",oneDateHotelIds,timestamp+"_"+k+"_"+j,days);
                    }
                    log.info("{} 当前价格coutTask，酒店处理完且酒店队列无数据： k={},j={}",timestamp,k,j);
                    return new Result<>();//return 结束当前
                }
                if(oneDateHotelIds.size()==timeHotel){
                    //发起异步线程，调用第三方接口
                    //log.info("调用task0",JSON.toJSONString(oneDateHotelIds),days,timestamp+"_"+k+"_"+j);
                    meituanPartTimeQueryPriceTask.executeCheckOneHotelGoods("ALL",oneDateHotelIds,timestamp+"_"+k+"_"+j,days);
                    //log.info("{} 当前价格coutTask，酒店处理完： k={},j={}",timestamp,k,j);
                    oneDateHotelIds = new ArrayList<>();
                }
            }
            /*try {
                Thread.sleep(10);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }*/
        }
        log.info("partTimeQueryPriceInfo {} 节点时间定时器主动查询1个月产品价格 结束时间 {},countTask={}",timestamp,DateUtil.getCurrTime(),countTask);

        return new Result();
    }

    /**
     * 定时器主动查询1个月产品库存
     * @return
     */
    @PostMapping("/partTimeQueryInvInfo")
    @ApiOperation(value = "定时器主动查询1个月产品库存",notes="必须经过auth授权")
    public Result<Object> partTimeQueryInvInfo(@RequestBody Map map){

        /*String timestamp = (String)map.get("timestamp");

        log.info("allTimeQueryInvInfo {} 定时器主动查询1个月产品库存  执行时间 {}",timestamp,DateUtil.getCurrTime());

        int countTask = 8;
        if(null != redisTemplate.opsForValue().get("allTimeQueryInvInfo_countTask")){
            countTask = (Integer) redisTemplate.opsForValue().get("allTimeQueryInvInfo_countTask");
        }

        List<String> hotelIds = new ArrayList<>();
        for (int i = 0; i < countTask; i++) {
            String oneHotelId = (String)redisTemplate.opsForList().rightPop(MeituanConstants.);//每pop一次该list集合中vo少一个
            if(!ObjectUtils.isEmpty(oneHotelId)){
                hotelIds.add(oneHotelId);
            }else{
                log.info("allTimeQueryInvInfo 定时器主动查询1个月产品库存 {} MeituanConstants.  已获取完 当前一轮 所有酒店  {}",timestamp,DateUtil.getCurrTime());
                break;
            }
        }
        log.info("allTimeQueryInvInfo {} 定时器主动查询1个月产品库存 当前一次定时器触发，待跑异步线程，酒店数量 hotelIds={}",timestamp,JSON.toJSONString(hotelIds));
        for (int i = 0; i < hotelIds.size(); i++) {
            //一个酒店一个异步线程
            meituanQueryInvTask.executeCheckHotelGoodsInvtory(hotelIds.get(i),timestamp+"_"+i);
            try {
                Thread.sleep(2);//线程也可能并发
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        log.info("allTimeQueryInvInfo {}  定时器主动查询1个月产品库存 结束时间 {}",timestamp,DateUtil.getCurrTime());*/

        return new Result();
    }

}
